home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 December / PCWDEC07.iso / Software / Freeware / FlashGot 0.6.4 / chrome / flashgot.jar / content / flashgot / FlashGot.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-08-29  |  35.1 KB  |  1,656 lines

  1. /***** BEGIN LICENSE BLOCK *****
  2.     FlashGot - a Firefox extension for external download managers integration
  3.     Copyright (C) 2004-2006 Giorgio Maone - g.maone@informaction.com
  4.     
  5.     contributors:
  6.     Max Velasques (wxDownload Fast support)
  7.     Zhang Ji (BitComet support)
  8.     YuanHongYe (new Thunder support)
  9.  
  10.     
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  
  25. ***** END LICENSE BLOCK *****/
  26.  
  27. #include "FlashGot.h"
  28.  
  29. FGCOMGuard *FGCOMGuard::instance = NULL;
  30. int FGCOMGuard::refCount = 0;
  31.  
  32.  
  33. #define BUF_SIZE 1024
  34.  
  35. char g_buf[BUF_SIZE];
  36. wchar_t g_wbuf[BUF_SIZE];
  37.  
  38.  
  39.  
  40. extern void fail(char *msg, int code) 
  41. {
  42.     MessageBox(NULL, msg,
  43.                       "FlashGot Error",
  44.                       MB_OK | MB_ICONERROR);
  45.     exit(code);
  46. }
  47.  
  48.  
  49. using namespace std;
  50.  
  51.  
  52.  
  53.  
  54.  
  55. class DMSAddUrlFamily :
  56.     public DMSupportCOM
  57. {
  58.     void dispatch(const DownloadInfo *downloadInfo)
  59.     {
  60.         CookieManager cm(downloadInfo);
  61.         HELPER(h);
  62.         int linksCount=downloadInfo->linksCount;
  63.         if(linksCount>0)
  64.         {
  65.             if(linksCount<2) {
  66.                 LinkInfo link=downloadInfo->links[0];
  67.                 VARIANT v[3];
  68.                 v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  69.                 v[2].bstrVal=link.url;
  70.                 v[1].bstrVal=link.comment;
  71.                 v[0].bstrVal=downloadInfo->referer;
  72.                 h.invoke("AddUrl",v,3);
  73.             } 
  74.             else 
  75.             {
  76.                 FGArray fgArray(downloadInfo);
  77.                 h.invoke("AddUrlList",fgArray.asVariant(),1);
  78.             }
  79.         }
  80.     }
  81. };
  82.  
  83.  
  84.  
  85.  
  86. class DMSFlashGet :
  87.     public DMSAddUrlFamily
  88. {
  89.  
  90. protected:
  91.     
  92.     const char * getProgId() { return "JetCar.Netscape"; }
  93.     
  94. public:
  95.     
  96.     const char * getName() { return "FlashGet"; }
  97.  
  98. };
  99.  
  100.  
  101.  
  102. class DMSFreeDownloadManager :
  103.     public DMSupportCOM
  104. {
  105.  
  106. protected:
  107.  
  108.     const char * getProgId() { return "WG.WGUrlListReceiver"; }
  109.  
  110. public:
  111.     
  112.     const char * getName() { return "Free Download Manager"; }
  113.  
  114.     void dispatch(const DownloadInfo *downloadInfo )
  115.     {
  116.         
  117.         int linksCount=downloadInfo->linksCount;
  118.         if(linksCount>0)
  119.         {
  120.             CookieManager cm(downloadInfo);
  121.             const char *progId;
  122.             char *methodName;
  123.  
  124.             if(linksCount<2)
  125.             {
  126.                 progId="WG.WGUrlReceiver";
  127.                 methodName="AddDownload";
  128.             } else {
  129.                 progId=getProgId();
  130.                 methodName="AddURLToList";
  131.             }
  132.  
  133.             FGCOMHelper fdm(progId);
  134.             fdm.set("Referer",downloadInfo->referer);
  135.             LinkInfo *links=downloadInfo->links;
  136.             for(int j=0; j< linksCount; j++) {
  137.                 LinkInfo l=links[j];
  138.                 fdm.set("Url",l.url);
  139.                 fdm.set("Comment",l.comment);
  140.                 fdm.invoke(methodName);
  141.             }
  142.             if(linksCount>1) fdm.invoke("ShowAddUrlListDialog");
  143.             
  144.         }
  145.     }
  146.     
  147. };
  148.  
  149. class DMSBitComet :
  150.     public DMSupportCOM
  151. {
  152.     protected:
  153.         const char * getProgId() { return "BitCometAgent.BcAgent.1"; }
  154.  
  155.     public:
  156.         const char * getName() { return "BitComet"; }
  157.  
  158.         void dispatch(const DownloadInfo *downloadInfo)
  159.         {
  160.             HELPER(h);
  161.  
  162.             int linksCount = downloadInfo->linksCount;
  163.             if (linksCount > 0)
  164.             {
  165.                 if (linksCount < 2)
  166.                 {
  167.                     VARIANT v[5];
  168.  
  169.                     // write title to param array
  170.                     v[0].vt = VT_NULL;
  171.                     
  172.                     // write ref URL to param array
  173.                     v[1].vt = VT_BSTR;
  174.                     v[1].bstrVal = downloadInfo->referer;
  175.  
  176.                     // write URL title to param array
  177.                     v[2].vt = VT_BSTR;
  178.                     v[2].bstrVal = downloadInfo->links[0].comment;
  179.  
  180.                     // write target URL to param array
  181.                     v[3].vt = VT_BSTR;
  182.                     v[3].bstrVal = downloadInfo->links[0].url;
  183.  
  184.                     // write html content to param array
  185.                     v[4].vt = VT_NULL;
  186.  
  187.                     h.invoke("AddLink", v, 5);
  188.                 }
  189.                 else
  190.                 {
  191.                     VARIANT v[5];
  192.  
  193.                     HRESULT hResult = S_OK;
  194.  
  195.                     SAFEARRAY            *pSA_URL = NULL;
  196.                     SAFEARRAY            *pSA_FLASH = NULL;
  197.                     SAFEARRAYBOUND        bound_url[1];
  198.                     SAFEARRAYBOUND        bound_flash[1];
  199.  
  200.                     bound_url[0].lLbound = 0;
  201.                     bound_url[0].cElements = 2 * linksCount;
  202.  
  203.                     bound_flash[0].lLbound = 0;
  204.                     bound_flash[0].cElements = 0;
  205.  
  206.                     // write Flash URL link list to param array
  207.                     if ( NULL == (pSA_FLASH = SafeArrayCreate(VT_VARIANT, 1, bound_flash)) )
  208.                     {
  209.                         return;
  210.                     }
  211.  
  212.                     v[0].vt = VT_ARRAY | VT_BYREF | VT_VARIANT;
  213.                     v[0].pparray = &pSA_FLASH;
  214.  
  215.                     // write <URL, link title> pair list to param array
  216.                     if ( NULL == (pSA_URL = SafeArrayCreate(VT_VARIANT, 1, bound_url)) )
  217.                     {
  218.                         return;
  219.                     }
  220.                     long index[1];
  221.                     index[0] = 0;
  222.  
  223.                     VARIANT  varStr;
  224.  
  225.                     varStr.vt = VT_BSTR;
  226.  
  227.                     for (int i=0; i < linksCount; i++)
  228.                     {
  229.                         varStr.bstrVal = downloadInfo->links[i].url;
  230.                         hResult = SafeArrayPutElement(pSA_URL, index, &varStr);
  231.                         if (hResult != S_OK)
  232.                         {
  233.                             return;
  234.                         }
  235.                         index[0]++;
  236.  
  237.                         varStr.bstrVal = downloadInfo->links[i].comment;
  238.                         hResult = SafeArrayPutElement(pSA_URL, index, &varStr);
  239.                         if (hResult != S_OK)
  240.                         {
  241.                             return;
  242.                         }
  243.                         index[0]++;
  244.                     }
  245.  
  246.                     v[1].vt = VT_ARRAY | VT_BYREF | VT_VARIANT;
  247.                     v[1].pparray = &pSA_URL;
  248.  
  249.                     // write page title to param array
  250.                     BSTR page_title = SysAllocString(L"title");
  251.                     v[2].vt = VT_BSTR;
  252.                     v[2].bstrVal = page_title;
  253.  
  254.                     // write refer url to param array
  255.                     BSTR refer_url = SysAllocString(L"unknown");
  256.                     v[3].vt = VT_BSTR;
  257.                     v[3].bstrVal = refer_url;//downloadInfo->referer;
  258.  
  259.                     // write html content to param array
  260.                     BSTR html_content = SysAllocString(L"unkown");
  261.                     v[4].vt = VT_BSTR;
  262.                     v[4].bstrVal = html_content;
  263.  
  264.                     // invoke AddLinkList()
  265.                     h.invoke("AddLinkList", v, 5);
  266.  
  267.                     // cleanup
  268.                     SafeArrayDestroy(pSA_URL);
  269.                     SafeArrayDestroy(pSA_FLASH);
  270.                     SysFreeString(page_title);
  271.                     SysFreeString(refer_url);
  272.                     SysFreeString(html_content);
  273.                 }
  274.             }
  275.         }
  276. };
  277.  
  278.  
  279.  
  280. class DMSFreshDownload :
  281.     public DMSupportCOM
  282. {
  283.  
  284.  
  285. protected:
  286.     
  287.     const char * getProgId() { return "fdcatch.fdnscatcher"; }
  288.     
  289. public:
  290.     
  291.     const char * getName() { return "FreshDownload"; }
  292.  
  293.     void dispatch(const DownloadInfo *downloadInfo)
  294.     {
  295.         HELPER(h);
  296.         CookieManager cm(downloadInfo);
  297.         if(downloadInfo->opType==OP_ONE) 
  298.         {
  299.             LinkInfo l=downloadInfo->links[0];
  300.             VARIANT v[3];
  301.             v[2].vt=v[1].vt=VT_BSTR;
  302.             v[2].bstrVal=l.url; // URL
  303.             v[1].bstrVal=downloadInfo->referer; // referer
  304.             v[0].vt=VT_INT;
  305.             v[0].intVal=0; // quiet (0 means "show dialog")
  306.             h.invoke("AddURL",v,3);
  307.         } 
  308.         else
  309.         {
  310.             h.invoke("AddUrlList",FGArray(downloadInfo).asVariant(),1);
  311.         }
  312.     }
  313. };
  314.  
  315.  
  316. class DMSGetRight :
  317.     public DMSupport
  318. {
  319.  
  320. private:
  321.     static char *findGetRight(HKEY baseKey, char *leafPath, char *exeName) {
  322.         long res;
  323.         HKEY hk;
  324.         char *path=NULL;
  325.         
  326.  
  327.         if( (res=RegOpenKeyEx(baseKey,leafPath,0,KEY_QUERY_VALUE,&hk))==ERROR_SUCCESS)
  328.         {
  329.         
  330.         
  331.             char *installKey="InstallDir";
  332.             long pathLen=0;    
  333.             if((res=RegQueryValueEx(hk,installKey,0,NULL,NULL,(LPDWORD)&pathLen))==ERROR_SUCCESS) 
  334.             {
  335.                 BOOL lastAttempt;
  336.                 do {
  337.                     lastAttempt=exeName==NULL;
  338.                     if(lastAttempt) exeName="getright.exe";
  339.                     
  340.                     path=new char[pathLen+strlen(exeName)+2];
  341.                     BOOL fileExists=FALSE;
  342.                     if((res=RegQueryValueEx(hk,installKey,0,NULL,(LPBYTE)path,(LPDWORD)&pathLen))==ERROR_SUCCESS)
  343.                     {
  344.                         strcat(path,"\\");
  345.                         strcat(path,exeName);
  346.                         struct stat statbuf;
  347.                         fileExists=!stat(path,&statbuf);  
  348.                     }
  349.                     if(!fileExists) {
  350.                         delete path;
  351.                         path=NULL;
  352.                         if(!lastAttempt) exeName=NULL;
  353.                     }
  354.                 } while(! (path || lastAttempt) );
  355.             }
  356.             RegCloseKey(hk);    
  357.         }
  358.         
  359.         return path;
  360.         
  361.     }
  362.     
  363.     static char *findGetRight(char *exeName) 
  364.     {
  365.         char *path;
  366.         if(    ( path=findGetRight(HKEY_CURRENT_USER,"Software\\Headlight\\GetRight\\Config",exeName) )
  367.              || ( path=findGetRight(HKEY_LOCAL_MACHINE,"Software\\Headlight\\GetRight",exeName) ) )
  368.         {
  369.             return path;
  370.         }
  371.         throw "Can't find GetRight executable";
  372.     }
  373.  
  374.     static char *createCmdLine(char *path, char *opts, char *arg) {
  375.         char *cmdLine=new char[strlen(path)+strlen(opts)+strlen(arg)+6];
  376.         sprintf(cmdLine,"\"%s\" %s %s",path,opts,arg);
  377.         return cmdLine;
  378.     }
  379.  
  380. public:
  381.     
  382.     const char * getName() { return "GetRight"; }
  383.  
  384.     void check() 
  385.     {
  386.         delete findGetRight(NULL);
  387.     }
  388.     void dispatch(const DownloadInfo *downloadInfo) 
  389.     {
  390.         char *cmdLine=NULL;
  391.         char *path=NULL;
  392.         char *exeName;
  393.         char *arg;
  394.         char *tgargs=NULL;
  395.         if(downloadInfo->linksCount) {
  396.             exeName="togetright.exe";
  397.             if( strlen(downloadInfo->extras[2]) 
  398.                 && (strcmp("old",downloadInfo->extras[2])==0))
  399.             {
  400.                 arg = downloadInfo->links[0].url; // CHECK ME!!!
  401.             } else
  402.             {
  403.                 char *pattern = "/referer=%s /cookie=%s /url=%s";
  404.                 char *cookie = downloadInfo->links[0].cookie;
  405.                 char *referer = downloadInfo->referer;
  406.                 char *url = downloadInfo->links[0].url;
  407.                 
  408.                 arg=tgargs=new char[
  409.                     strlen(referer)+
  410.                     strlen(cookie)+
  411.                     strlen(url)+
  412.                     strlen(pattern)];
  413.  
  414.                 sprintf(tgargs,pattern,
  415.                     referer,cookie,url);
  416.             }
  417.         } else {
  418.             exeName=NULL;
  419.             arg=(char *)downloadInfo->referer;
  420.         }
  421.         /*
  422.         // GetRight doesn't work if not already started... needs more investigation
  423.  
  424.         if(!FindWindow(NULL, "GetRight "))
  425.         {
  426.             path = findGetRight(NULL);
  427.             if(createProcess(cmdLine = createCmdLine(path, "", ""), NULL))
  428.             {
  429.                 for(int j = 100; j-- > 0;) // 10 secs for GetRight to show up
  430.                 {
  431.                     if(FindWindow(NULL, "GetRight ")) break;
  432.                     sleep(100);
  433.                     if(j == 50) createProcess(cmdLine, NULL);
  434.                 }
  435.             }
  436.             if(cmdLine) delete[] cmdLine;
  437.         }
  438.         */
  439.         if(exeName || !path) path = findGetRight(exeName);
  440.         
  441.         BOOL ret=createProcess(cmdLine=createCmdLine(path = findGetRight(exeName),
  442.             downloadInfo->extras[0],
  443.             arg),NULL);
  444.         if(tgargs) delete [] tgargs;
  445.         // supplementary post-command
  446.         if( ret && (!exeName) && strlen(downloadInfo->extras[1])) 
  447.         {
  448.             if(cmdLine) delete[] cmdLine;
  449.             Sleep(500);
  450.             createProcess(cmdLine = createCmdLine(path,
  451.                 downloadInfo->extras[1],
  452.                 ""),NULL);
  453.         }
  454.         if(cmdLine) delete [] cmdLine;
  455.         if(path) delete [] path;
  456.         if(!ret) throw "Can't launch GetRight";
  457.     }
  458. };
  459.  
  460. class DMSHiDownload :
  461.     public DMSupportCOM
  462. {
  463.  
  464.  
  465. protected:
  466.     
  467.     const char * getProgId() { return "NetMoles.NetMoles"; }
  468.     
  469. public:
  470.     
  471.     const char * getName() { return "HiDownload"; }
  472.  
  473.     
  474.     void dispatch(const DownloadInfo *downloadInfo)
  475.     {
  476.         CookieManager cm(downloadInfo);
  477.         
  478.         
  479.         HELPER(h);
  480.         
  481.         
  482.         if(downloadInfo->linksCount == 1 && !FindWindow("HiDownload", NULL))
  483.         {
  484.             VARIANT v[2];
  485.             v[1].vt = v[0].vt = VT_BSTR;
  486.             LinkInfo l = downloadInfo->links[0];
  487.             v[1].bstrVal = l.url;
  488.             v[0].bstrVal = l.comment;
  489.             h.invoke("NMAddUrl", v, 2);
  490.         } else
  491.         {
  492.             FGArray fgArray(downloadInfo);
  493.             VARIANT v;
  494.             v.vt=VT_BYREF | VT_VARIANT;
  495.             v.pvarVal=fgArray.asVariant();
  496.             h.invoke("NMAddAllUrl", &v, 1);
  497.         }
  498.         
  499.     }
  500. };
  501.  
  502. class DMSInstantGet :
  503.     public DMSAddUrlFamily
  504. {
  505. protected:
  506.     const char * getProgId() { return "InstantGet.AddUrl"; }
  507. public:
  508.     const char * getName() { return "InstantGet"; }
  509. };
  510.  
  511.  
  512. #import "IDManTypeInfo.tlb" 
  513. #include "IDManTypeInfo.h"                
  514. #include "IDManTypeInfo_i.c"  
  515.  
  516. class DMSInternetDownloadManager :
  517.     public DMSupportCOM
  518. {
  519.  
  520.  
  521. protected:
  522.     
  523.     const char * getProgId() { return "IDMGetAll.IDMAllLinksProcessor"; }
  524.     
  525. public:
  526.     
  527.     const char * getName() { return "Internet Download Manager"; }
  528.  
  529.     
  530.     void dispatch(const DownloadInfo *downloadInfo)
  531.     {
  532.         long lc = downloadInfo->linksCount;
  533.         if(lc<1) return;
  534.  
  535.         LinkInfo *links=downloadInfo->links;
  536.         LinkInfo *l;
  537.  
  538.         ICIDMLinkTransmitter2* pIDM;
  539.         HRESULT hr = CoCreateInstance(CLSID_CIDMLinkTransmitter, NULL, CLSCTX_LOCAL_SERVER,
  540.                     IID_ICIDMLinkTransmitter2, (void**)&pIDM);
  541.         if (S_OK != hr) return;
  542.  
  543.         if(lc < 2)
  544.         {
  545.             VARIANT reserved;
  546.             reserved.vt=VT_EMPTY;
  547.             l = &links[0];
  548.             
  549.             pIDM->SendLinkToIDM2(l->url, downloadInfo->referer, l->cookie, l->postdata,
  550.                     NULL, NULL, NULL, NULL, 0,
  551.                     reserved, reserved);
  552.         } 
  553.         else 
  554.         {
  555.             
  556.             SAFEARRAY *pSA = NULL;
  557.             SAFEARRAYBOUND bound[2];
  558.             bound[0].lLbound = 0;
  559.             bound[0].cElements = lc;
  560.             bound[1].lLbound = 0;
  561.             bound[1].cElements = 4;
  562.             if ( pSA = SafeArrayCreate(VT_BSTR, 2, bound) )
  563.             {
  564.                 long index[2];
  565.                 CComBSTR url, cookie, comment;
  566.  
  567.                 for(long j = 0; j < lc; j++)
  568.                 {
  569.                     index[0] = j;
  570.                     l = &links[j];
  571.                     
  572.                     index[1] = 0;
  573.  
  574.                     url = (LPCOLESTR)l->url;
  575.                     cookie = (LPCOLESTR)l->cookie;
  576.                     comment = (LPCOLESTR)l->comment;
  577.  
  578.                     SafeArrayPutElement(pSA, index, url);
  579.             
  580.                     index[1] = 1;
  581.                     SafeArrayPutElement(pSA, index, cookie);
  582.             
  583.                     index[1] = 2;
  584.                     SafeArrayPutElement(pSA, index, comment);
  585.             
  586.                     index[1] = 3;
  587.                     SafeArrayPutElement(pSA, index, NULL);
  588.                 }
  589.                 VARIANT array;
  590.                 VariantInit(&array);
  591.                 array.vt = VT_ARRAY | VT_BSTR;
  592.                 array.parray = pSA;
  593.                 pIDM->SendLinksArray(downloadInfo->referer, &array);
  594.                 SafeArrayDestroy(pSA);
  595.             }
  596.         }
  597.         pIDM->Release();
  598.     }
  599. };
  600.  
  601.  
  602.  
  603. class DMSLeechGetBase :
  604.     public DMSupportCOM
  605. {
  606.  
  607. public:
  608.     
  609.     
  610.     void dispatch(const DownloadInfo *downloadInfo) 
  611.     {    
  612.         HELPER(h);
  613.         CookieManager cm(downloadInfo);
  614.         if(downloadInfo->linksCount>0) 
  615.         {
  616.             h.invoke(downloadInfo->opType==OP_ONE?"AddURL":"Wizard", downloadInfo->links[0].url);
  617.         } 
  618.         else 
  619.         {
  620.             h.invoke("Parse",downloadInfo->referer);
  621.         }
  622.     }
  623. };
  624.  
  625. class DMSLeechGet2002 :
  626.     public DMSLeechGetBase
  627. {
  628.     
  629. protected:
  630.     const char * getProgId() 
  631.     {
  632.         return "LeechGetIE.AddURL";
  633.     }
  634. public:
  635.     const char * getName() { return "LeechGet 2002"; }
  636. };
  637.  
  638. class DMSLeechGet :
  639.     public DMSLeechGetBase
  640. {
  641. protected:
  642.     const char * getProgId() 
  643.     {
  644.         return "LeechGetIE.LeechIE";
  645.     }
  646. public:
  647.     const char * getName() { return "LeechGet"; }
  648. };
  649.  
  650. class DMSMass_Downloader :
  651.     public DMSupportCOM
  652. {
  653.  
  654.  
  655. protected:
  656.     
  657.     const char * getProgId() { return "MassDown.AddUrl.1"; }
  658.     
  659. public:
  660.     
  661.     const char * getName() { return "Mass Downloader"; }
  662.  
  663.     void dispatch(const DownloadInfo *downloadInfo)
  664.     {
  665.         
  666.         
  667.         int linksCount=downloadInfo->linksCount;
  668.         if(linksCount<1) return;
  669.         {
  670.             VARIANT v[3];
  671.             v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  672.             HELPER(h);
  673.             CookieManager cg(downloadInfo);
  674.             DISPID di_AddUrlWithReferer;
  675.             h.getMemberID("AddUrlWithReferer",&di_AddUrlWithReferer);
  676.             
  677.             if(linksCount>1) {
  678.                 v[1].bstrVal=v[0].bstrVal=bstr_t("Begin.");
  679.                 h.invoke("AddUrl",v,2);
  680.             }
  681.             v[0].bstrVal=downloadInfo->referer;
  682.             LinkInfo *links=downloadInfo->links;
  683.             for(int j=0; j<linksCount; j++) {
  684.                 LinkInfo l=links[j];
  685.                 v[2].bstrVal=l.url;
  686.                 v[1].bstrVal=l.comment;
  687.                 h.invoke(&di_AddUrlWithReferer,v,3);
  688.             }
  689.             if(linksCount>1) {
  690.                 v[1].bstrVal=v[0].bstrVal=bstr_t("End.");
  691.                 h.invoke("AddUrl",v,2);
  692.             }
  693.         }
  694.     }
  695. };
  696.  
  697. class DMSNetAnts :
  698.     public DMSAddUrlFamily
  699. {
  700. protected:
  701.     const char * getProgId() { return "NetAnts.API"; }
  702. public:
  703.     const char * getName() { return "NetAnts"; }
  704. };
  705.  
  706.  
  707. class DMSNet_Transport :
  708.     public DMSupportCOM
  709. {
  710.  
  711. protected:
  712.     
  713.     const char * getProgId() { return "NTIEHelper.NTIEAddUrl"; }
  714.  
  715. public:
  716.     const char * getName() { return "Net Transport"; }
  717.  
  718.     void dispatch(const DownloadInfo *downloadInfo)
  719.     {
  720.         CookieManager cm(downloadInfo);
  721.         
  722.         int linksCount=downloadInfo->linksCount;
  723.         bstr_t *parms=downloadInfo->rawParms;
  724.         
  725.         SAFEARRAY *psaa[2]=
  726.         {
  727.             FGArray::createSafeArray(linksCount),
  728.             FGArray::createSafeArray(linksCount)
  729.         };
  730.  
  731.         VARIANT vstr;
  732.         vstr.vt = VT_BSTR;
  733.         long ix[]={0};
  734.         for(int j=1; ix[0]<linksCount; ix[0]++) 
  735.         {
  736.             for(int a=0; a<2; a++) 
  737.             {
  738.                 vstr.bstrVal=parms[j++];
  739.                 SafeArrayPutElement(psaa[a], ix, &vstr);
  740.             }
  741.             j+=2; // skipping cookie & postData;
  742.         }
  743.         
  744.         //AddList(referrer,urls, remarks);
  745.         VARIANT v[3];
  746.         v[2].vt=VT_BSTR;
  747.         v[2].bstrVal=downloadInfo->referer;
  748.         v[1].vt=v[0].vt=VT_VARIANT | VT_BYREF ;
  749.         SafeArrayAccessData(psaa[0], (void **)&(v[1].pvarVal));
  750.         SafeArrayAccessData(psaa[1], (void **)&(v[0].pparray));
  751.         HELPER(h);
  752.         h.invoke("AddList",v,3);
  753.  
  754.         SafeArrayUnlock(psaa[1]);
  755.         SafeArrayUnlock(psaa[0]);
  756.         SafeArrayDestroy(psaa[0]);
  757.         SafeArrayDestroy(psaa[1]);
  758.     }
  759. };
  760.  
  761.  
  762.  
  763. class DMSNet_Transport2 :
  764.     public DMSNet_Transport
  765. {
  766.  
  767. protected:
  768.     
  769.     const char * getProgId() { return "NXIEHelper.NXIEAddURL"; }
  770.  
  771. public:
  772.     const char * getName() { return "Net Transport 2"; }
  773.  
  774. };
  775.  
  776. class DMSWestByte :
  777.     public DMSupportCOM
  778. {
  779.  
  780. public:
  781.  
  782.  
  783.     void dispatch(const DownloadInfo *downloadInfo)
  784.     {
  785.         int linksCount=downloadInfo->linksCount;
  786.         bstr_t *parms=downloadInfo->rawParms;
  787.         
  788.         if(linksCount>0)
  789.         {
  790.             
  791.             VARIANT v[2];
  792.             v[0].vt = VT_BSTR ;
  793.             v[0].bstrVal=downloadInfo->referer; // referer
  794.             HELPER(h);
  795.             CookieManager cm(downloadInfo);
  796.             if(linksCount==1) 
  797.             {
  798.                 v[1].vt = VT_BSTR; // VBScript Array
  799.                 v[1].bstrVal=downloadInfo->links[0].url;
  800.                 
  801.                 h.invoke("AddURL",v,2);
  802.             } 
  803.             else 
  804.             { 
  805.  
  806.                 FGArray fgArray(linksCount * 2);
  807.                 LinkInfo *links=downloadInfo->links;
  808.                 for (int j=0; j < linksCount; j++) {
  809.                     LinkInfo l=links[j];
  810.                     fgArray.addString(l.url);
  811.                     fgArray.addString(l.comment);
  812.                 }
  813.                 
  814.                 fgArray.asVariant(&v[1]);
  815.                 
  816.                 h.invoke("AddURLs",v,2);
  817.  
  818.             }
  819.         }
  820.     }
  821.     
  822. };
  823.  
  824.  
  825.  
  826. class DMSOrbit :
  827.     public DMSupportCOM
  828. {
  829. protected:
  830.     const char * getProgId() { return "Orbitmxt.Orbit"; }
  831.     
  832. public:
  833.     const char * getName() { return "Orbit"; }
  834.  
  835.     void dispatch(const DownloadInfo *downloadInfo)
  836.     {
  837.         CookieManager cm(downloadInfo);
  838.  
  839.         HELPER(h);
  840.         int linksCount=downloadInfo->linksCount;
  841.         if(linksCount>0)
  842.         {
  843.             if(linksCount<2)
  844.             {
  845.                 LinkInfo link=downloadInfo->links[0];
  846.                 VARIANT v[4];
  847.                 
  848.                 v[3].vt=v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  849.                 
  850.                 v[0].bstrVal=link.cookie;
  851.                 v[1].bstrVal=downloadInfo->referer;
  852.                 v[2].bstrVal=link.comment;
  853.                 v[3].bstrVal=link.url;
  854.  
  855.                 h.invoke("download",v,4);
  856.             }
  857.             else 
  858.             {
  859.                 VARIANT v[4];
  860.                 FGArray urlArray(linksCount);
  861.                 FGArray txtArray(linksCount);
  862.                 for(int i=0;i<linksCount;i++)
  863.                 {
  864.                     urlArray.addString( downloadInfo->links[i].url );
  865.                     txtArray.addString( downloadInfo->links[i].comment );
  866.                 }
  867.  
  868.                 urlArray.asVariant(&v[3]);
  869.                 txtArray.asVariant(&v[2]);
  870.                 v[1].vt=v[0].vt=VT_BSTR;
  871.                 v[1].bstrVal=downloadInfo->referer;
  872.                 v[0].bstrVal=downloadInfo->links[0].cookie;
  873.                 
  874.                 h.invoke("downloadList",v, 4);
  875.             }
  876.         }
  877.     }
  878. };
  879.  
  880.  
  881. class DMSwxDownloadFast :
  882.     public DMSupport
  883. {
  884.  
  885. private:
  886.     static char *findProgram(HKEY baseKey, char *leafPath) {
  887.         long res;
  888.         HKEY hk;
  889.         char *exe=NULL;
  890.         
  891.         if( (res=RegOpenKeyEx(baseKey,leafPath,0,KEY_QUERY_VALUE,&hk))==ERROR_SUCCESS)
  892.         {
  893.             char *exepath="ExePath";
  894.             long pathLen=0;    
  895.             if((res=RegQueryValueEx(hk,exepath,0,NULL,NULL,(LPDWORD)&pathLen))==ERROR_SUCCESS) 
  896.             {
  897.                 exe=new char[pathLen+1];
  898.                 BOOL fileExists=FALSE;
  899.                 if((res=RegQueryValueEx(hk,exepath,0,NULL,(LPBYTE)exe,(LPDWORD)&pathLen))==ERROR_SUCCESS)
  900.                 {
  901.                     struct stat statbuf;
  902.                     fileExists=!stat(exe,&statbuf);  
  903.                 }
  904.                 if(!fileExists) {
  905.                     delete exe;
  906.                     exe=NULL;
  907.                 }
  908.             }
  909.             RegCloseKey(hk);    
  910.         }
  911.         
  912.         return exe;
  913.         
  914.     }
  915.     
  916.     static char *findProgram() 
  917.     {
  918.         char *path;
  919.         if(    (path = findProgram(HKEY_CURRENT_USER,"Software\\wxWidgets Program\\wxDownload Fast")) ||
  920.             (path = findProgram(HKEY_LOCAL_MACHINE,"Software\\wxWidgets Program\\wxDownload Fast")) // Ma1 20061510
  921.         ) return path;
  922.         
  923.         throw "Can't find wxDownload Fast executable";
  924.     }
  925.  
  926.     static char *createCmdLine(char *path, char *arg) {
  927.         char *cmdLine=new char[strlen(path)+strlen(arg)+8];
  928.         sprintf(cmdLine,"\"%s\" %s ",path,arg);
  929.         return cmdLine;
  930.     }
  931.  
  932. public:
  933.     
  934.     const char * getName() { return "wxDownload Fast"; }
  935.  
  936.     void check() 
  937.     {
  938.         delete findProgram();
  939.     }
  940.     void dispatch(const DownloadInfo *downloadInfo) 
  941.     {
  942.         char *cmdLine=NULL;
  943.         char *path=NULL;
  944.         char *arg;
  945.         char *tgargs=NULL;
  946.         BOOL ret = false;
  947.         if(downloadInfo->linksCount)
  948.         {
  949.             char *referer=downloadInfo->referer;
  950.  
  951.             if (downloadInfo->linksCount == 1)
  952.             {
  953.                 char *pattern="--reference=%s \"%s\"";
  954.                 char *url=downloadInfo->links[0].url;
  955.                 arg=tgargs=new char[
  956.                     strlen(referer)+
  957.                     strlen(url)+
  958.                     strlen(pattern)];
  959.                 sprintf(tgargs,pattern,referer,url);
  960.             }
  961.             else
  962.             {
  963.                 char *pattern="--reference=%s --list=\"%s\"";
  964.                 FILE * fp; 
  965.                 char tmppath[1024];
  966.                 if (GetTempPath(1024,tmppath)==0)
  967.                 {
  968.                     strcpy(tmppath, "c:");
  969.                 }
  970.                 strcat(tmppath, "TEMPURL.LST");
  971.  
  972.                 if(!(fp = fopen(tmppath, "w"))) 
  973.                 { 
  974.                     throw "FlashGot can't create file TEMPURL.LST for wxDownload Fast";
  975.                 } 
  976.                 for(int j=0,count=downloadInfo->linksCount; j<count; j++)
  977.                 {
  978.                     fputs(downloadInfo->links[j].url,fp);
  979.                     fputc('\n',fp);
  980.                 }
  981.                 fclose(fp);
  982.                 arg=tgargs=new char[
  983.                     strlen(referer)+
  984.                     strlen(tmppath)+
  985.                     strlen(pattern)];
  986.                 sprintf(tgargs,pattern,referer,tmppath);
  987.             }
  988.             ret=createProcess(cmdLine=createCmdLine(path=findProgram(),
  989.                 arg),NULL);
  990.         }
  991.  
  992.         if(tgargs) delete [] tgargs;
  993.         if(cmdLine)    delete [] cmdLine;
  994.         if(path) delete [] path;
  995.  
  996.         if(!ret) throw "Can't launch wxDownload Fast";
  997.     }
  998. };
  999.  
  1000.  
  1001. class DMSDownloadMaster :
  1002.     public DMSWestByte
  1003. {
  1004. protected:
  1005.     const char * getProgId() { return "DMIE.MoveURL"; }
  1006. public:
  1007.     const char * getName() { return "Download Master"; }
  1008. };
  1009.  
  1010. class DMSInternetDownloadAccelerator :
  1011.     public DMSWestByte
  1012. {
  1013. protected:
  1014.     const char * getProgId() { return "IDAIE.MoveURLIDA"; }
  1015. public:
  1016.     const char * getName() { return "Internet Download Accelerator"; }
  1017. };
  1018.  
  1019. class DMSReGet :
  1020.     public DMSupportCOM
  1021. {
  1022.     
  1023.     protected:
  1024.     const char * getProgId() 
  1025.     {
  1026.         return "ClickCatcher.DownloadAllFromContextMenu";
  1027.     }
  1028. public:
  1029.     const char * getName() { return "ReGet"; }
  1030.     
  1031.     void dispatch(const DownloadInfo *downloadInfo) 
  1032.     {    
  1033.         int linksCount=downloadInfo->linksCount;
  1034.         
  1035.         VARIANT v[5];
  1036.         v[0].vt=v[1].vt=v[2].vt=v[3].vt=v[4].vt=VT_BSTR;
  1037.         bstr_t referer=downloadInfo->referer; // referer
  1038.         
  1039.         FGCOMHelper *regetAll=NULL;
  1040.         DISPID di_AddDownload;
  1041.     
  1042.         if(linksCount>1) {
  1043.             regetAll=new FGCOMHelper(getProgId());
  1044.             regetAll->getMemberID("AddDownloadToList",&di_AddDownload);
  1045.         } else if(linksCount==1) {
  1046.             LinkInfo l=downloadInfo->links[0];
  1047.             if(strlen(l.postdata)) {
  1048.                 try 
  1049.                 {
  1050.                     FGCOMHelper dl("ReGetDx.RegetDownloadApi");
  1051.                     dl.set("Url",l.url);
  1052.                     dl.set("Referer",referer);
  1053.                     dl.set("Cookie",l.cookie);
  1054.                     dl.set("Info",l.comment);
  1055.                     dl.set("PostData",l.postdata);
  1056.                     dl.invoke("AddDownload");
  1057.                     return;
  1058.                 } catch(...) {}
  1059.             }
  1060.         }
  1061.         CookieManager cm(downloadInfo);
  1062.         LinkInfo *links=downloadInfo->links;
  1063.         for(int j=0; j<linksCount; j++) 
  1064.         {    
  1065.             LinkInfo l=links[j];
  1066.             
  1067.             for(int attempts=120; attempts-->0;) 
  1068.             { // we give ReGet 2mins to wake up
  1069.                 try 
  1070.                 {
  1071.                     FGCOMHelper dl("ClickCatcher.DownloadFromContextMenu");
  1072.                     
  1073.                     dl.set("Url",l.url);
  1074.                     dl.set("Referer",referer);
  1075.                     dl.set("Info",l.comment);
  1076.                     dl.set("Cookie",l.cookie); // -- it seems a dummy property, we use CookieManager which works
  1077.                     if(regetAll) {
  1078.                         VARIANT vdl;
  1079.                         vdl.vt=VT_DISPATCH;
  1080.                         vdl.pdispVal=dl.getIDispatch();
  1081.                         regetAll->invoke(&di_AddDownload,&vdl,1);
  1082.                     } else {
  1083.                         dl.invoke("AddDownload");
  1084.                     }
  1085.  
  1086.                     break;
  1087.                 } 
  1088.                 catch(_com_error ce)
  1089.                 {
  1090.                     Sleep(1000);
  1091.                     if(attempts==0) throw "ReGet timeout";
  1092.                 }
  1093.             }
  1094.         }
  1095.  
  1096.         if(regetAll) try 
  1097.         { 
  1098.             regetAll->invoke("UrlList",NULL,0);
  1099.             delete regetAll;
  1100.         } catch(...) {}
  1101.     }
  1102. };
  1103.  
  1104.  
  1105. class DMSStarDownloader :
  1106.     public DMSupportCOM
  1107. {
  1108.  
  1109.  
  1110. protected:
  1111.     
  1112.     const char * getProgId() { return "SDExt.StarDownExt"; }
  1113.     
  1114. public:
  1115.     
  1116.     const char * getName() { return "Star Downloader"; }
  1117.  
  1118.     void dispatch(const DownloadInfo *downloadInfo)
  1119.     {
  1120.         
  1121.         HELPER(downloader);
  1122.         DISPID di_DownloadURL;
  1123.         downloader.getMemberID("DownloadURL",&di_DownloadURL);
  1124.         
  1125.         VARIANT v[2];
  1126.         v[0].vt = v[1].vt = VT_BSTR;
  1127.         v[0].bstrVal = downloadInfo->referer; // referrer
  1128.         LinkInfo *links=downloadInfo->links;
  1129.         for (long j=0, len=downloadInfo->linksCount; j < len ; j++) { 
  1130.             v[1].bstrVal=links[j].url;
  1131.             downloader.invoke(&di_DownloadURL,v,2);
  1132.         }
  1133.     }
  1134. };
  1135.  
  1136. class DMSThunder :
  1137.     public DMSupportCOM
  1138. {
  1139.  
  1140.  
  1141. protected:
  1142.  
  1143.     const char * getProgId() { return "ThunderAgent.Agent"; }
  1144.     
  1145. public:
  1146.     
  1147.     const char * getName() { return "Thunder"; }
  1148.  
  1149.     void dispatch(const DownloadInfo *downloadInfo)
  1150.     {
  1151.         CookieManager cm(downloadInfo);
  1152.         HELPER(h);
  1153.         VARIANT v[8];
  1154.         v[7].vt = v[6].vt = v[5].vt = v[4].vt = v[3].vt = VT_BSTR;
  1155.         v[2].vt = v[1].vt = v[0].vt = VT_INT;
  1156.  
  1157.         LinkInfo *links=downloadInfo->links;
  1158.         for (long j=0, len=downloadInfo->linksCount; j<len ; j++) 
  1159.         { 
  1160.             v[7].bstrVal=links[j].url;
  1161.             v[6].bstrVal=_bstr_t("");
  1162.             v[5].bstrVal=_bstr_t("");
  1163.             v[4].bstrVal=links[j].comment;
  1164.             v[3].bstrVal=downloadInfo->referer;
  1165.             v[2].intVal=-1;
  1166.             v[1].intVal=0;
  1167.             v[0].intVal=-1;
  1168.             h.invoke("AddTask",v,8);
  1169.         }
  1170.  
  1171.         h.invoke("CommitTasks");
  1172.     }
  1173. };
  1174.  
  1175. class DMSGigaGet : 
  1176.     public DMSupportCOM
  1177. {
  1178.     
  1179. protected:
  1180.     const char * getProgId() { return "GigaGetBho.CatchRightClick.1"; }
  1181.     
  1182. public:
  1183.     const char * getName() { return "GigaGet"; }
  1184.  
  1185.     void dispatch(const DownloadInfo *downloadInfo)
  1186.     {
  1187.         CookieManager cm(downloadInfo);
  1188.         HELPER(h);
  1189.         VARIANT v[2];
  1190.         v[0].vt= VT_BYREF;
  1191.  
  1192.         FGArray fgArray(downloadInfo);
  1193.         v[1].vt=VT_BYREF | VT_VARIANT;
  1194.         v[1].pvarVal=fgArray.asVariant();
  1195.         h.get("AddAllUrl",v,1);
  1196.     }
  1197. };
  1198.  
  1199. class DMSThunderOld :
  1200.     public DMSGigaGet
  1201. {
  1202.  
  1203.  
  1204. protected:
  1205.  
  1206.     const char * getProgId() { return "Xunleibho.CatchRightClick.1"; }
  1207.     
  1208. public:
  1209.     
  1210.     const char * getName() { return "Thunder (Old)"; }
  1211.  
  1212. };
  1213.  
  1214.  
  1215. class DMSTrueDownloader :
  1216.     public DMSupportCOM
  1217. {
  1218.  
  1219.  
  1220. protected:
  1221.     const char * getProgId() { return "TrueDownloaderProject.TrueDownloader"; }
  1222.     
  1223. public:
  1224.     const char * getName() { return "TrueDownloader"; }
  1225.  
  1226.     void dispatch(const DownloadInfo *downloadInfo)
  1227.     {
  1228.         
  1229.         HELPER(downloader);
  1230.         DISPID di_MenuURL;
  1231.         downloader.getMemberID("MenuURL",&di_MenuURL);
  1232.         
  1233.         VARIANT v[3];
  1234.         v[0].vt = v[1].vt = v[2].vt = VT_BSTR;
  1235.         v[1].bstrVal = downloadInfo->referer; // referrer
  1236.         LinkInfo *links=downloadInfo->links;
  1237.         for (long j=0, len=downloadInfo->linksCount; j < len ; j++) 
  1238.         { 
  1239.             v[2].bstrVal=links[j].url;
  1240.             v[0].bstrVal=links[j].cookie;
  1241.             downloader.invoke(&di_MenuURL,v,3);
  1242.         }
  1243.     }
  1244. };
  1245.  
  1246. class DMSWellGet :
  1247.     public DMSupport
  1248. {
  1249.     
  1250.     const char * getProgId() { return "NxApi.myComponent"; }
  1251.     
  1252. public:
  1253.     
  1254.     const char * getName() { return "WellGet"; }
  1255.     
  1256.     void check() {
  1257.         dispatch(NULL);
  1258.     }
  1259.  
  1260.     void dispatch(const DownloadInfo *downloadInfo)
  1261.     {
  1262.         
  1263.     
  1264.         HKEY hk = NULL;
  1265.         BOOL ok = false;
  1266.         CString apppath;
  1267.         if(downloadInfo && strlen((char *)(downloadInfo->extras[2]))) 
  1268.         { // explicit path
  1269.             apppath = (char *)downloadInfo->extras[2];
  1270.         } else if(RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\WellGet"),0,KEY_QUERY_VALUE,&hk)==ERROR_SUCCESS)
  1271.         {    
  1272.             DWORD dwDisposition = 1023;
  1273.             BYTE szpath[1024];
  1274.             DWORD type_1=REG_SZ ; 
  1275.             if(RegQueryValueEx(hk, NULL, NULL,&type_1, szpath, &dwDisposition)==ERROR_SUCCESS)
  1276.             {    
  1277.                 apppath.Format("%s\\WellGet.exe",szpath);
  1278.             }
  1279.             RegCloseKey(hk);
  1280.         }
  1281.         
  1282.         // check WellGet path
  1283.         struct stat statbuf;
  1284.         if(stat(apppath,&statbuf))  throw "Can't find WellGet executable";
  1285.         
  1286.         if(downloadInfo && downloadInfo->linksCount > 0)
  1287.         {
  1288.             CookieManager cm(downloadInfo);
  1289.             CString parms;
  1290.  
  1291.             if(downloadInfo->opType==OP_ONE) 
  1292.             {
  1293.                 try // try COM first, to overcome command line bug in latest (1.25 - 0118) build
  1294.                 {
  1295.                     HELPER(h);
  1296.     
  1297.                     LinkInfo l=downloadInfo->links[0];
  1298.                     VARIANT v[3];
  1299.                     v[2].vt=v[1].vt=v[0].vt=VT_BSTR;
  1300.                     v[2].bstrVal=l.url; // URL
  1301.                     v[1].bstrVal=l.comment;
  1302.                     v[0].bstrVal=downloadInfo->referer; // referer
  1303.                     h.invoke("AddURL",v,3);
  1304.                     return;
  1305.                 } catch(...)
  1306.                 { // fall back to command line
  1307.                     LinkInfo l=downloadInfo->links[0];
  1308.                     
  1309.                     parms.Format("-r:\"%s\" -c:\"%s\" \"%s\"",
  1310.                         (char *)downloadInfo->referer,
  1311.                         (char *)l.comment, (char *)l.url);
  1312.                 } 
  1313.             }
  1314.             else 
  1315.             {
  1316.                 LinkInfo *links=downloadInfo->links;
  1317.                 
  1318.                 FILE * fp; 
  1319.                 char path[1024];
  1320.                 if (GetTempPath(1024,path)==0)
  1321.                 {
  1322.                     strcpy(path,"c:");
  1323.                 }
  1324.                 strcat(path,"TEMPURL.TXT");
  1325.  
  1326.                 if(!(fp = fopen(path, "w"))) 
  1327.                 { 
  1328.                     throw "FlasGot can't create file TEMPURL.TXT for WellGet";
  1329.                 } 
  1330.                 fputs(downloadInfo->referer,fp);
  1331.                 fputc('\n',fp);
  1332.                 for(int j=0,count=downloadInfo->linksCount; j<count; j++) {
  1333.                     LinkInfo l=links[j];
  1334.                     fputs(l.url,fp);
  1335.                     fputc('\n',fp);
  1336.                     fputs(l.comment,fp);
  1337.                     fputc('\n',fp);
  1338.                 }
  1339.                 fclose(fp);
  1340.                 parms="-u addlist";
  1341.             }
  1342.             ShellExecute(NULL,"open",
  1343.                 apppath,parms,"", SW_SHOW );
  1344.         }
  1345.  
  1346.     }
  1347.         
  1348.     
  1349.     
  1350. };
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356. // [END DOWNLOAD MANAGER SUPPORT CLASSES]
  1357.  
  1358.  
  1359. typedef struct _DMSNode {
  1360.     unsigned int id;
  1361.     DMSupport *dms;
  1362.     _DMSNode *prev;
  1363. } DMSNode;
  1364.  
  1365.  
  1366.  
  1367. class DMSFactory 
  1368. {
  1369. private:
  1370.     static DMSFactory *instance;
  1371.     DMSNode *last;
  1372.     DMSupport *add(DMSupport *dms) {
  1373.         if(!last) {
  1374.             (last=new DMSNode())->prev=NULL;
  1375.             last->id=1;
  1376.         } else {
  1377.             DMSNode *newNode=new DMSNode();
  1378.             newNode->prev=last;
  1379.             newNode->id=last->id << 1;
  1380.             last=newNode;
  1381.         }
  1382.         return last->dms=dms;
  1383.     }
  1384.  
  1385.     DMSFactory() : last(NULL) {
  1386.  
  1387.  
  1388.         add(new DMSBitComet());
  1389.         add(new DMSDownloadAcceleratorPlus());
  1390.         add(new DMSDownloadMaster());
  1391.         add(new DMSFlashGet());
  1392.         add(new DMSFreeDownloadManager());
  1393.         add(new DMSFreshDownload());
  1394.         add(new DMSGetRight());
  1395.         add(new DMSGigaGet());
  1396.         add(new DMSHiDownload());
  1397.         add(new DMSInstantGet());
  1398.         add(new DMSInternetDownloadAccelerator());
  1399.         add(new DMSInternetDownloadManager());
  1400.         add(new DMSLeechGet2002());
  1401.         add(new DMSLeechGet());
  1402.         add(new DMSMass_Downloader());
  1403.         add(new DMSNetAnts());
  1404.         add(new DMSNet_Transport());
  1405.         add(new DMSNet_Transport2());
  1406.         add(new DMSOrbit());
  1407.         add(new DMSReGet());
  1408.         add(new DMSStarDownloader());
  1409.         add(new DMSTrueDownloader());
  1410.         add(new DMSThunder());
  1411.         add(new DMSThunderOld());
  1412.         add(new DMSWellGet());
  1413.         add(new DMSwxDownloadFast());
  1414.  
  1415. }
  1416.  
  1417. public:
  1418.     
  1419.     static DMSFactory *getInstance() {
  1420.         return instance?instance:instance=new DMSFactory();        
  1421.     }
  1422.     
  1423.     
  1424.     DMSupport *getDMS(char *name) {
  1425.         DMSNode *cursor=last;
  1426.         for(; cursor && strcmp(cursor->dms->getName(),name); cursor=cursor->prev);
  1427.         return cursor 
  1428.             ?cursor->dms
  1429.             :NULL;    
  1430.     }
  1431.     
  1432.     unsigned int checkAll() {
  1433.         unsigned int retVal=0;
  1434.         fprintf(stdout,"FlashGot Win Bridge %s\r\n",VERSION);
  1435.         FGCOMGuard::addClient();
  1436.         for(DMSNode *cursor=last; cursor; cursor=cursor->prev) {
  1437.             try {
  1438.                 fprintf(stdout,"%s|",cursor->dms->getName());
  1439.                 cursor->dms->check();
  1440.                 fprintf(stdout,"OK\n");
  1441.                 continue;
  1442.             } catch(_com_error ce) {
  1443.                 fprintf(stdout,"BAD\nCOM error: %s\n", ce.ErrorMessage());
  1444.             } catch(...) {
  1445.                 fprintf(stdout,"BAD\nunexpected unknown error!\n");
  1446.             }
  1447.             retVal |= cursor->id;
  1448.         }
  1449.         FGCOMGuard::removeClient();
  1450.         return retVal;
  1451.     }
  1452.  
  1453.  
  1454.  
  1455.     ~DMSFactory() {
  1456.         DMSNode *cursor=last;
  1457.         while( cursor ) {
  1458.             delete cursor->dms;
  1459.             last=cursor;
  1460.             cursor=last->prev;
  1461.             delete last;
  1462.         }
  1463.     }
  1464. };
  1465. DMSFactory * DMSFactory::instance=NULL;
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475. DMSupport* createDMS(char *name) {
  1476.     DMSupport *res=DMSFactory::getInstance()->getDMS(name);
  1477.     if(res) return res;
  1478.     sprintf(g_buf,"Unsupported Download Manager %s", name);
  1479.     fail(g_buf,-8000);
  1480.     return NULL;
  1481. }
  1482.  
  1483. wchar_t *UTF8toUnicode(const char *src) {
  1484.     return src && (
  1485.         MultiByteToWideChar(CP_UTF8,0,src,-1,  g_wbuf, BUF_SIZE) 
  1486.         || MultiByteToWideChar(CP_ACP,0,src,-1,g_wbuf, BUF_SIZE)
  1487.         )
  1488.         ? g_wbuf : L""
  1489.         ;
  1490. }
  1491.  
  1492. bstr_t * readLine(FILE *stream, bstr_t *buffer) 
  1493. {
  1494.     
  1495.     bool isLine=false;
  1496.     for(char *res; res=fgets(g_buf,BUF_SIZE,stream); )
  1497.     {
  1498.         size_t lastPos=strlen(res)-1;
  1499.         while(lastPos>=0 && 
  1500.             (res[lastPos]==0x0a || res[lastPos]==0x0d)
  1501.             )
  1502.         {
  1503.             res[lastPos--]='\0';
  1504.             isLine=true;
  1505.         }
  1506.         
  1507.         buffer->Assign(*buffer + UTF8toUnicode((const char*) res));
  1508.         if(isLine) break;
  1509.     }
  1510.     return buffer;
  1511. }
  1512.  
  1513.  
  1514.  
  1515. int performTest(char *outfname)
  1516. {
  1517.     if(outfname) 
  1518.     {
  1519.         freopen(outfname,"w", stdout);
  1520.         freopen(outfname,"a", stderr);
  1521.     }
  1522.     exit(DMSFactory::getInstance()->checkAll());
  1523. }
  1524.  
  1525.  
  1526. void parseHeader(DownloadInfo *downloadInfo, char *header_buf)
  1527. {
  1528. #define HEADER_COUNT 4
  1529.     char *header[HEADER_COUNT];
  1530.     char *cur=header_buf;
  1531.     for(int j=0; j<HEADER_COUNT ; ) 
  1532.     {
  1533.         if( (header[j++]=cur)  && (cur=strchr(cur,';')) ) 
  1534.         {
  1535.             cur[0]='\0';
  1536.             ++cur;
  1537.         } 
  1538.         else
  1539.         {
  1540.             if(j!=HEADER_COUNT) fail("Malformed header",17);    
  1541.             break;
  1542.         }
  1543.     }
  1544.  
  1545.     downloadInfo->linksCount=atoi(header[0]);
  1546.     downloadInfo->dmName=header[1];
  1547.     int typeId=atoi(header[2]);
  1548.     downloadInfo->opType = (typeId<OP_MIN||typeId>OP_MAX)
  1549.         ?OP_ALL:(OpType)typeId;
  1550.     downloadInfo->folder = bstr_t(UTF8toUnicode((const char *)header[3]));
  1551. }
  1552.  
  1553. void processJobFile(FILE *f)
  1554. {
  1555.     DMSupport *dms = NULL;
  1556.     const char *errMsg="Download manager not properly installed.\n%s";
  1557.     BOOL completed=FALSE;
  1558.     try 
  1559.     {
  1560.         DownloadInfo downloadInfo;
  1561.  
  1562.         char header_buf[BUF_SIZE];
  1563.         if(fgets(header_buf,BUF_SIZE,f))
  1564.         {
  1565.             parseHeader(&downloadInfo,header_buf);
  1566.             int linksCount=downloadInfo.linksCount;
  1567.             int parmsCount=1 + linksCount*4 + EXTRAS_COUNT; // referer + (url + info  + cookie + postdata) * 4 + referer cookie + referer referer :-)
  1568.  
  1569.             bstr_t *parms=downloadInfo.rawParms=new bstr_t[parmsCount];
  1570.             
  1571.             LinkInfo *links=downloadInfo.links=new LinkInfo[linksCount];
  1572.             
  1573.             for(int j=0; j<parmsCount; j++) {
  1574.                 parms[j]="";
  1575.                 bstr_t *buffer=&parms[j];
  1576.                 readLine(f,buffer);
  1577.             }
  1578.             
  1579.             downloadInfo.referer=parms[0];
  1580.             downloadInfo.links=(LinkInfo *) &parms[1];
  1581.             downloadInfo.extras=&parms[parmsCount-EXTRAS_COUNT];
  1582.  
  1583.             (dms=createDMS(downloadInfo.dmName))->dispatch(&downloadInfo);
  1584.             printf("%s",downloadInfo.folder);
  1585.         }
  1586.         completed=TRUE;
  1587.     } 
  1588.     catch(_com_error ce)
  1589.     {
  1590.         sprintf(g_buf,errMsg,ce.ErrorMessage());
  1591.     }
  1592.     catch(char *ex) {
  1593.         sprintf(g_buf,errMsg,ex);
  1594.     } 
  1595.     //catch(...) {
  1596.     //    sprintf(g_buf,errMsg,"");
  1597.     //}
  1598.     
  1599.     if(dms) delete dms;
  1600.     
  1601.     if(!completed) fail(g_buf,0x02000);
  1602. }
  1603.  
  1604. int performDownload(char *fname)
  1605. {
  1606.     FILE *f;
  1607.     
  1608.     char *done=strcat(strcpy(new char[(strlen(fname)+6)],fname),".done");
  1609.     
  1610.     if(!(f=fopen(fname,"rb")))  
  1611.     {
  1612.         struct stat statbuf;
  1613.         if(stat(done,&statbuf)) // done file doesn't exist  
  1614.         {
  1615.             sprintf(g_buf,"Can't open file %s",fname);
  1616.             fail(g_buf,0x01000);
  1617.         } else {
  1618.             remove(done);
  1619.         }
  1620.     }
  1621.     else
  1622.     {    
  1623.         if(!feof(f))    
  1624.         {
  1625.             processJobFile(f);
  1626.         }
  1627.         else 
  1628.         {
  1629.             sprintf(g_buf,"Temporary file %s is empty",fname);
  1630.             fail(g_buf,0x03000);
  1631.         }
  1632.         fclose(f);
  1633.         
  1634.         if(!strstr(done,"test"))
  1635.         {
  1636.             remove(done);
  1637.             rename(fname,done);
  1638.         }
  1639.     }
  1640.     delete [] done;
  1641.     return 0;
  1642. }
  1643.  
  1644. int main(int argc, char* argv[])
  1645. {
  1646.     return (argc<2 || strcmp(argv[1],"-o") == 0 )
  1647.         ?performTest(argc>2?argv[2]:NULL)
  1648.         :performDownload(argv[1]);
  1649. }
  1650.  
  1651. int WINAPI
  1652. WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
  1653. {
  1654.     return main(__argc, __argv); 
  1655. }
  1656.